package main

func main() {
	/*
			1.GC 触发条件：
			（1）当前内存分配达到一定比例则触发
			（2）2 分钟没有触发过 GC 则触发 GC
			（3）手动触发，调用 runtime.GC()

				阈(yù)值（又叫临界值）：
					由一个 gcpercent 的变量控制的，当 新分配的内存 占 已在使用中的内存 的比例超过 gcprecent 时就会触发。
						比如一次回收完毕后，内存的使用量为 5M，那么下次回收的时机则是内存分配达到10M的时候。

					也就是说，并不是内存分配越多，垃圾回收频率越高。

					如果一直达不到内存大小的阈值呢？
					  这个时候 GC 就会被 定时时间 触发。
						比如一直达不到 10M，那就定时（默认 2min 触发一次）触发一次 GC 保证资源的回收。

			2.GC：垃圾回收机制（GC: Garbage Collection）
				注：
					阻塞状态 是Go调度的一个 待唤醒 的状态，是 不能被GC 的。

			（1）go V1.3之前 采用的 GC 是 ”标记回收法（mark & sweep）“：
				从根变量来时，遍历所有被引用对象，标记之后进行清除操作，对未标记对象进行回收。

											Stop The World 暂停范围
							╭━━━━━━━━━━━━━━━━━━━━━━━━━^━━━━━━━━━━━━━━━━━━━━━━━━━━━━╮
				┄┄┄┄┄┄┄┄┄┄> 启动 STW ————> Mark 标记 ————> Sweep 清除 ————> 停止 STW ┈┈┈┈┈┈┈┈┈┈>

				1、流程：
					第一步，暂停程序业务逻辑，找出不可达的对象，和可达对象。
					第二步，开始标记，程序找出它所有可达的对象，并做上标记。
					第三步，标记完了之后，然后开始清除未标记的对象．
					第四步，停止暂停，让程序继续跑。然后循环重复这个过程，直到 process 程序生命周期结束。

				2、缺点：
					1）SWT，Stop the world：让程序暂停，程序出现卡顿（重要问题）。
					2）标记需要扫描整个 heap
					3）清除数据会产生 heap 碎片
					4）将第四步和第三步换位置，缩短SWT的范围。

				3、如何从代码方面优化以减少 GC 导致的 SWT 的时间？
					1）减少对象的分配
					2）使用 sync.Pool

			（2）Go V1.5 采用 三色标记法：
				三色标记 最大的好处是可以 异步执行，从而可以以 中断时间极少的代价 或者 完全没有中断 来进行整个 GC。

				1、流程：
					对象用三种颜色表示（白、灰、黑）。
					第一步，就是只要是新创建的对象，默认的颜色都是标记为 “白色”。
					第二步，每次 GC 回收开始，然后从根节点开始遍历所有对象，把遍历到的对象从 白色 集合放入 “灰色” 集合。
					第三步，遍历 灰色 集合，将 灰色 对象 引用的其他对象 从 白色 集合放入 灰色 集合，之后将 此灰色 对象放入 黑色 集合。
					第四步，重复第三步，直到 灰色 中无任何对象。此时，所有的 白色变量 就一定是需要被清理的 垃圾 了。

				2、三色标记法 因为多了一个 白色 状态来存放不确定的对象，所以可以 异步地执行。

				3、优点：
					1）三色标记法掌握了更多 当前内存的信息，因此可以更加 精确地按需调度，而不用像标记清扫法那样只能定时执行。
					2）标记过程中是不需要 STW，它与程序是并发执行的，这就大大缩短了 STW 的时间。

				4、三色标记 最不希望发生的事：
					条件 1：一个 白色对象 被 黑色对象 引用（白色 被挂在 黑色 下）
					条件 2：灰色对象 与它之间的 可达关系的白色对象 遭到破坏（灰色 同时 弄丢了 该白色）

				两个条件 同时满足 时，会出现 对象丢失 现象！

				5、强三色不变式：强制性的 不允许黑色对象 引用 白色对象。（破坏条件1）
				   弱三色不变式：黑色对象可以引用白色对象，白色对象存在其他灰色对象对它的引用，或者可达它的链路上游存在灰色对象。（破坏条件2）

				6、屏障机制：
					插入屏障：对象被引用时，触发的机制
					删除屏障：对象被删除时，触发的机制
				插入写屏障：
					写屏障，即在内存写操作开始前，维护一个约束，从而确保清扫开始前，黑色对象不能引用白色对象。

					当标记和程序是并发执行的，这就会造成一个问题. 在标记过程中，有新的引用产生，可能会导致误清扫.
				  清扫开始前，标记为黑色的对象引用了一个新申请的对象，它肯定是白色的，而黑色对象不会被再次扫描，
				  那么这个白色对象无法被扫描变成灰色、黑色，它就会最终被清扫，而实际它不应该被清扫. 这就需要用到屏障技术。
				  Goland 采用写屏障，作用就是为了避免这类误清扫问题。

		3.垃圾回收优化：
			1）写屏障 可以让 goroutine 和 GC 同时运行。GC 过程中新分配的内存会被立即标记，用的正是写屏障技术，
			即 GC 过程中分配的内存不会在本轮 GC 中回收。

			2）为了防止内存分配过快，在 GC 执行的过程中，如果 goroutine 需要分配内存，
			那么该 goroutine 会参与一部分 GC 的工作，帮助 GC 做一部分工作。

	*/
}
